﻿using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.Entities.BPM_Process;
using NP.BPMReportPlatform.RecurringJobs.Dto.FlowManager;
using SqlSugar;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace NP.BPMReportPlatform.RecurringJobs
{
    /// <summary>
    /// 流程管理接口应用Job
    /// </summary>
    public class FlowManagerRecurringJob : BpmReportPlatformRecurringJob, IFlowManagerRecurringJob
    {
        private readonly SqlSugarClient _dbBusiness, _dbEngine, _dbProcess;

        public FlowManagerRecurringJob(ISqlSugarAppService sqlSugarAppService, IConfiguration configuration)
        {
            _dbBusiness = sqlSugarAppService.GetBusinessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _dbProcess = sqlSugarAppService.GetProcessInstance();
        }

        /// <summary>
        /// 自动补充流程丢失的FlowType
        /// </summary>
        public async Task AutoReplenishFlowTypeAsync()
        {
            var instanceNumberArray = await _dbBusiness.Queryable<StandardApproval>().Where(x => SqlFunc.IsNullOrEmpty(x.FlowType)).Select(x => x.InstanceId).ToArrayAsync();

            var instanceList = await _dbEngine.Queryable<Instances>().Where(x => SqlFunc.ContainsArray<string>(instanceNumberArray, x.Number)).
                Select(x => new FlowInstanceDto()
                {
                    InstanceId = x.Number,
                    ProcessName = x.Topic
                }).ToListAsync();

            var processNameArray = instanceList.Select(x => x.ProcessName).Distinct().ToArray();

            var processList = await _dbProcess.Queryable<Processes>().Where(x => SqlFunc.ContainsArray<string>(processNameArray, x.Name)).
                Select(x => new FlowInstanceDto()
                {
                    FlowType = x.BTID,
                    ProcessName = x.Name
                }).ToListAsync();

            var insProList = (from ins in instanceList
                              join proc in processList on ins.ProcessName equals proc.ProcessName
                              select new FlowInstanceDto()
                              {
                                  InstanceId = ins.InstanceId,
                                  FlowType = proc.FlowType,
                                  ProcessName = proc.ProcessName
                              }).ToList();

            if (insProList.Any())
            {
                var standardApprovalList = ObjectMapper.Map<List<FlowInstanceDto>, List<StandardApproval>>(insProList);
                await _dbBusiness.Updateable(standardApprovalList).
                    UpdateColumns(x => new { x.FlowType }).
                    WhereColumns(x => new { x.InstanceId }).ExecuteCommandAsync();
            }
        }
    }
}
